1. Field of the Invention
The present invention relates to computer instruction code. More specifically, the present invention relates to a method and an apparatus for a class initialization barrier in a multitasking virtual machine.
2. Related Art
Computer programs written in languages such as JAVA™ are compiled into a platform-independent code, which is executed on a virtual machine, such as a JAVA VIRTUAL MACHINE (JVM). A program that has been compiled into a platform-independent code has the advantage that it can execute on a virtual machine regardless of the underlying central processing unit and native code. The terms JAVA, JVM, and JAVA VIRTUAL MACHINE are trademarks or registered trademarks of SUN Microsystems, Inc. of Palo Alto, Calif.
A virtual machine typically includes an interpreter, which interprets the platform-independent code into native code to perform the desired operations. Interpreting the platform-independent code is an inherently slow operation. Therefore, many virtual machine implementations also include a dynamic compiler, which can compile at runtime the platform-independent code into the native code of the machine being used to host the virtual machine. Compiling the platform-independent code into the native code of the host machine can reduce the execution time of the program and, therefore, increase throughput.
Virtual machines for object-oriented programming languages with dynamic class loading typically load the code of a class when a program resolves a symbolic reference to that class for the first time. The class needs to be initialized subsequently when the program uses it for the first time. Loading and initialization of a class are two separate events. Initialization of a class may never take place even though the class has been loaded before. In the case of the Java programming language, the initialization of a class consists of executing some code, known as the class's static initializer, that brings the class's variables (also known as the static variables) to a well-defined initialized state. A virtual machine implementation may choose to set a class to the initialized state upon its loading when no action is required to initialize that class. For instance, in the Java programming language, no action is required to initialize a class when this class has no declared static initialization sequence, and either no non-final static variables, or non-final static variables that are all declared to be set to a default value. In this case, a virtual machine implementation can benefit from setting such initialization-less classes to the initialized state upon class loading.
A class initialization barrier is a sequence of native instructions that calls the virtual machine's runtime to initialize a class if it is not already initialized. Class initialization barriers are included in the implementation of those platform-independent instructions that may result in the very first use of a class (in the case of the Java programming language, there are 4 such instructions: getstatic, putstatic, invokestatic, new). The implementation of a platform-independent instruction can come in two flavors: (i) as a sequence of instruction that is part of the implementation of an interpreter of platform-independent instructions, (ii) or as a sequence of instruction generated by a dynamic compiler of platform-independent instructions.
Because class initialization barriers need only to be executed once per class, it is common practice in the implementation of non-multitasking virtual machines to have recourse to code-rewriting techniques to remove them and the overhead they induce. In other words, a class initialization barrier can simply be an instruction that calls the virtual machine runtime and that is removed, or replaced, by the runtime before returning from the call site.
A multitasking virtual machine (MVM) introduces further complication to these mechanisms. In order to save processing and memory, an MVM aims at sharing as much of the runtime representation of a class as possible between tasks. Targets for sharing include the platform-independent code, the meta-data describing the class, and the native code produced by the dynamic compiler. Code re-writing techniques can be harmful when code, whether it is platform-independent or produced by a runtime compiler, is shared between multiple tasks. For instance, rewriting native code to remove a class initialization barrier is incorrect when that code is shared between multiple tasks, since tasks that have not initialized the corresponding class may subsequently be given access to that class without it being initialized first.
Furthermore, part of the runtime representation of a class cannot be shared among tasks, in particular, the storage for the class's variables, the initialization state of the class for a given task, or the objects used in the first-class representation of the class (e.g., in the Java programming language, an instance of java.lang.Class).
It is the role of the multitasking virtual machine to efficiently implement the level of indirection needed to access the task-specific part of classes, most prominently, the storage for classes' variables, that correspond to the task on behalf of which code is being executed.
Hence, there is a need for a method and apparatus for an efficient class initialization barrier that enables sharing between multiple tasks/virtual machines of both interpreted platform-independent code and the equivalent native code produced at runtime. Because access to the global variables of classes can be frequent, and because such access must take place only if a class is initialized, class initialization barriers must also be made efficient for the case of class's variable access. Lastly, accesses to a class's variable in cases where it is known that the class is already initialized, or being initialized, should not pay any costs related to the class barrier mechanism.